#pragma once
#ifndef CLIENTSERVICE_H
#define CLIENTSERVICE_H

//标准库
#include <boost/noncopyable.hpp>
#include <boost/bind/bind.hpp>
#include <muduo/net/TcpClient.h>

#include <vector>
#include <semaphore.h>
#include <unordered_map>
#include <functional>
#include <string>

//第三方库
#include "json.hpp"

//自己的头文件
#include "user.hpp"
#include "group.hpp"
#include "public.hpp"

using std::string;
using std::function;
using nlohmann::json;

using muduo::net::TcpConnectionPtr;

//客户端功能函数类
class ClientService{
public:
    static ClientService* getInstacnce();
    ClientService();//构造函数

    //设置连接对象
    void setTcpConnectionPtr(const TcpConnectionPtr&);

    //客户端的主线程，负责用户输入逻辑处理等
    void mainloop();

    //客户端的IO线程收到服务端发来消息，IO线程解析消息类型，并且输出处理相关消息
    void IOparseMsgType(json& js);

    //显示登录注册退出菜单
    void showLoginMenu()const;

//自己归类的私有变量
private:
    //用于读写线程之间通信的信号量
    sem_t rwsem;

    //判断主线程是否在持续运行，如果用户使用quit功能，则准备退出
    bool isMainLoopRun;

    //控制主线程是否继续在聊天界面循环
    bool isChatMenuRun=false;

    //程序主菜单（登录、注册、退出界面）的功能handler回调函数表
    std::unordered_map<string,std::function<void()> > mainMenuHandler;

    //客户端连接的服务器对象
    TcpConnectionPtr _conn;

//自己归类的私有函数
private:
    //登录功能
    void login();

    //注册功能
    void reg();

    //退出功能
    void quit();

public:
    //上面是自己的代码修改优化
    //下面是从旧版本客户端搬过来的屎山代码
    //-------全局函数声明--------

    //显示当前登录成功的用户的基本信息（纯打印）
    void showCurrentUserData();

    //获取系统时间（聊天时需要添加时间信息）
    string getCurrentTime();

    //聊天程序主界面
    void ChatMenu();


//本来提示不在类里面的函数
    //处理登录的响应逻辑
    void doLoginResponse(json& responseLogin);
    
    //处理注册逻辑函数
    void doRegResponse(json& responseJson);

    

    
private:
    //-------全局变量-------

    

    //记录登录状态的原子类型，因为是多线程访问，所以保证原子性
    std::atomic_bool m_isLoginSuccess{false};

    //存储该客户端所登录的用户的信息
    User m_currentUser;

    //存储该客户端所登录的用户的好友列表
    vector<User> m_currentUserFriendList;

    //记录当前用户的群组列表
    vector<Group> m_currentUserGroupsList;

    

    //各功能命令和他们的功能描述，格式描述
    std::unordered_map<string, string> commandMap = {
    {"help", "显示所有支持的命令，格式help"},
    {"chat", "一对一聊天，格式chat:friendid:message"},
    {"addfriend", "添加好友，格式addfriend:friendid"},
    {"creategroup", "创建群组，格式creategroup:groupname:groupdesc"},
    {"addgroup", "加入群组，格式addgroup:groupid"},
    {"groupchat", "群聊，格式groupchat:groupid:message"},
    {"loginout", "注销，格式loginout"}};

    //注册功能，各功能代码与函数指针绑定
    //这里的function<void(int,string)>中
    //int指的是传递clinentfd
    //string指的是用户输入的命令行，如：chat:friendid:message
    std::unordered_map<std::string, std::function<void(std::string)>> commandHandlerMap;


    //下面是用户输入功能命令相关代码
    // 帮助提示函数，相当于控制台常见到的 xxx -help
    void help(string);
    // 聊天功能命令
    void chat(string);
    // 添加好友命令
    void addfriend(string);
    // 创建群组命令
    void creategroup(string);
    // 加入群组命令
    void addgroup(string);
    // 群组聊天命令
    void groupchat(string);
    // 退出账号命令
    void loginout(string);

};


#endif